From 783c30219891e873c9ea07fb83b603b647ef3d47 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 12 May 2016 13:34:42 +0200 Subject: [PATCH] wayland: Avoid spurious crossing events from master touch device Only generate crossing events on wl_touch.down for the virtual master device used for touch events, and only whenever this virtual device actually moves across surfaces. This behavior resembles better what is expected in X11, where the pointer is warped to the touch position on XITouchBegin. This avoids the double emission of leave events when the pointer emulating touch is lifted, that crossing event will be instead generated when/if the focus surface changes. https://bugzilla.gnome.org/show_bug.cgi?id=766314 --- gdk/wayland/gdkdevice-wayland.c | 46 +++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 2da74dea9e..1e3bc8336e 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -2071,6 +2071,33 @@ mimic_pointer_emulating_touch_info (GdkDevice *device, pointer->surface_y = touch->y; } +static void +touch_handle_master_pointer_crossing (GdkWaylandSeat *seat, + GdkWaylandTouchData *touch, + uint32_t time) +{ + GdkWaylandPointerData *pointer; + + pointer = GDK_WAYLAND_DEVICE (seat->touch_master)->pointer; + + if (pointer->focus == touch->window) + return; + + if (pointer->focus) + { + emulate_touch_crossing (pointer->focus, NULL, + seat->touch_master, seat->touch, touch, + GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, time); + } + + if (touch->window) + { + emulate_touch_crossing (touch->window, NULL, + seat->touch_master, seat->touch, touch, + GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, time); + } +} + static void touch_handle_down (void *data, struct wl_touch *wl_touch, @@ -2097,9 +2124,7 @@ touch_handle_down (void *data, if (touch->initial_touch) { - emulate_touch_crossing (touch->window, NULL, - seat->touch_master, seat->touch, touch, - GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, time); + touch_handle_master_pointer_crossing (seat, touch, time); GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = touch; mimic_pointer_emulating_touch_info (seat->touch_master, touch); } @@ -2133,16 +2158,7 @@ touch_handle_up (void *data, _gdk_wayland_display_deliver_event (seat->display, event); if (touch->initial_touch) - { - GdkWaylandPointerData *pointer_info; - - emulate_touch_crossing (touch->window, NULL, - seat->touch_master, seat->touch, touch, - GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, time); - GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = NULL; - pointer_info = GDK_WAYLAND_DEVICE (seat->touch_master)->pointer; - g_clear_object (&pointer_info->focus); - } + GDK_WAYLAND_DEVICE(seat->touch_master)->emulating_touch = NULL; gdk_wayland_seat_remove_touch (seat, id); } @@ -2193,10 +2209,6 @@ touch_handle_cancel (void *data, { touch = GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch; GDK_WAYLAND_DEVICE (wayland_seat->touch_master)->emulating_touch = NULL; - emulate_touch_crossing (touch->window, NULL, - wayland_seat->touch_master, wayland_seat->touch, - touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, - GDK_CURRENT_TIME); } g_hash_table_iter_init (&iter, wayland_seat->touches); -- 2.30.2